package com.wang.interview.reference;

import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;
import java.util.concurrent.TimeUnit;

/**
 * @author: wang
 * @date: 2021/8/12 21:01
 * @description: 软引用和弱引用
 * 注意引用对象是指的，引用传递，回收的是引用关系。但是如果这个传递给弱引用的是强引用关系，那么这个强引用没有消失之前，弱引用也不会被回收。
 * 本例的 integer 和 string 就是 强引用，所以直接赋值字面量，由于有常量池的机制，导致出现不会回收的问题
 * 默认强引用，不会回收；
 * 软引用内存不足时（oom之前）回收；
 * 弱引用 gc 就回收
 *
 * ->> 踩个大坑，string = null；不会产生 GC ， 原因是，直接使用字面量创建的字符串存在于堆的常量池中
 */
public class T1 {
    @Override
    protected void finalize() throws Throwable {
        System.out.println("垃圾被回收了");
    }

    public static void main(String[] args) {
        T1 t1 = new T1();
        //String str = "触发gc";
        //String str = new String("触发gc");  // 置为 null 不会 gc
        //System.out.println(str == "触发gc");        // false
        //String str = new String(new byte[]{1,2,3});  // str = null; 但是原本的对象还在？ 不清楚为什么不回收。
        Integer i = 0;
        String key = "弱引用map每次gc都会回收所有数据";
        SoftReference<Integer> softReference = new SoftReference<>(1);
        WeakReference<Integer> weakReference = new WeakReference<>(-200);  // 数字超出127 的时候就超出常量池范围了，就会被回收

        WeakHashMap<String, Integer> weakHashMap = new WeakHashMap<>();
        weakHashMap.put(key, i);
        System.out.println(softReference.get());
        System.out.println(weakReference.get());
        System.out.println(weakHashMap);
        System.out.println("============================");
        //str = null;
        t1 = null;
        System.gc();
        try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println(softReference.get());
        System.out.println(weakReference.get());
        System.out.println(weakHashMap);
        System.out.println("============================");
        weakHashMap.put(key, i);
        key = null;
        System.out.println(weakHashMap);

        /**
         * 1
         * 2
         * {弱引用map每次gc都会回收所有数据=0}
         * ============================
         * 1
         * 2                                         // 依旧没有回收
         * {弱引用map每次gc都会回收所有数据=0}          // 不会回收key
         * ============================
         * {弱引用map每次gc都会回收所有数据=0}           // map里的key实际上时copy的原key的一份内存地址，所以两者已然无关
         */

    }
}
